// 这些变量用于管理等待执行的任务列表和任务队列和其执行的状态信息：
let taskList = [];
let totalTaskCount = 0;
let currentTaskNumber = 0;
let taskHandle = null;
// 要交互DOM元素的变量
let totalTaskCountElem = document.getElementById("totalTaskCount");
let currentTaskNumberElem = document.getElementById("currentTaskNumber");
let progressBarElem = document.getElementById("progress");
let startButtonElem = document.getElementById("startButton");
let logElem = document.getElementById("log");

// 其他项目设置一对变量
let logFragment = null;
let statusRefreshScheduled = false;

// 排队任务
function enqueueTask(taskHandler, taskData) {
  taskList.push({
    handler: taskHandler,
    data: taskData
  });

  totalTaskCount++;

  if (!taskHandle) {
    taskHandle = requestIdleCallback(runTaskQueue, { timeout: 1000 });
  }

  scheduleStatusRefresh();
}

// 执行任务
function runTaskQueue(deadline) {
  while ((deadline.timeRemaining() > 0 || deadline.didTimeout) && taskList.length) {
    let task = taskList.shift();
    currentTaskNumber++;

    task.handler(task.data);
    scheduleStatusRefresh();
  }

  if (taskList.length) {
    taskHandle = requestIdleCallback(runTaskQueue, { timeout: 1000} );
  } else {
    taskHandle = 0;
  }
}

// 安排显示的更新
function scheduleStatusRefresh() {
  if (!statusRefreshScheduled) {
    requestAnimationFrame(updateDisplay);
    statusRefreshScheduled = true;
  }
}

// 更新显示
function updateDisplay() {
  let scrolledToEnd = logElem.scrollHeight - logElem.clientHeight <= logElem.scrollTop + 1;

  if (totalTaskCount) {
    if (progressBarElem.max != totalTaskCount) {
      totalTaskCountElem.textContent = totalTaskCount;
      progressBarElem.max = totalTaskCount;
    }

    if (progressBarElem.value != currentTaskNumber) {
      currentTaskNumberElem.textContent = currentTaskNumber;
      progressBarElem.value = currentTaskNumber;
    }
  }

  if (logFragment) {
    logElem.appendChild(logFragment);
    logFragment = null;
  }

  if (scrolledToEnd) {
      logElem.scrollTop = logElem.scrollHeight - logElem.clientHeight;
  }

  statusRefreshScheduled = false;
}

// 向记录添加文本
function log(text) {
  if (!logFragment) {
      logFragment = document.createDocumentFragment();
  }

  let el = document.createElement("div");
  el.innerHTML = text;
  logFragment.appendChild(el);
}

// 任务处理器
function logTaskHandler(data) {
  log("<strong>Running task #" + data.text + "</strong>");

  for (i=0; i<data.count; i+=1) {
    log(currentTaskNumber+'-'+(i+1).toString() + ": " + new Date().toLocaleTimeString());
  }
}

function getRandomIntInclusive(min, max) {
  return min + Math.floor(Math.random()*(max - min));
}

// 主程序
function decodeTechnoStuff() {
  totalTaskCount = 0;
  currentTaskNumber = 0;
  updateDisplay();
  logElem.innerHTML = '';

  let n = getRandomIntInclusive(100, 200);

  for (i=0; i<n; i++) {
    let taskData = {
      count: getRandomIntInclusive(75, 150),
      text: "This text is from task number " + (i+1).toString() + " of " + n
    };

    enqueueTask(logTaskHandler, taskData);
  }
}

document.getElementById("startButton").addEventListener("click", decodeTechnoStuff, false);